<template>
  <div class="components-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="container">
        <div class="header-content">
          <div class="title-section">
            <h1>组件库</h1>
            <p class="description">
              探索 ComfyUI 的全部组件，快速找到你需要的功能
            </p>
          </div>
          <div class="search-box">
            <input
              type="text"
              v-model="searchQuery"
              placeholder="搜索组件..."
              @input="handleSearch"
            />
          </div>
        </div>
      </div>
    </div>

    <!-- 主要内容区 -->
    <div class="main-content">
      <div class="container">
        <!-- 分类导航 -->
        <div class="categories">
          <button
            v-for="category in categories"
            :key="category.id"
            :class="[
              'category-btn',
              { active: currentCategory === category.id },
            ]"
            @click="currentCategory = category.id"
          >
            {{ category.name }}
          </button>
        </div>

        <!-- 组件列表 -->
        <div class="components-grid">
          <div
            v-for="component in filteredComponents"
            :key="component.id"
            class="component-card"
            @click="navigateToDetail(component.id)"
          >
            <div class="component-icon">
              <img :src="component.icon" :alt="component.name" />
            </div>
            <div class="component-info">
              <h3>{{ component.name }}</h3>
              <p>{{ component.description }}</p>
            </div>
            <div class="component-tags">
              <span v-for="tag in component.tags" :key="tag" class="tag">
                {{ tag }}
              </span>
            </div>
          </div>

          <!-- 加载状态提示 -->
          <div v-if="loading" class="loading-indicator">
            <div class="spinner"></div>
            <span>加载中...</span>
          </div>

          <!-- 没有更多数据提示 -->
          <div
            v-if="!hasMore && filteredComponents.length > 0"
            class="no-more"
          >
            没有更多组件了
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import { fetchAllComponents } from '../services/api'; // 引入获取组件的 API 方法
import { ElMessage } from 'element-plus'; // 引入 ElMessage 组件
import { useRouter } from 'vue-router';

// 分类数据
const categories = [
  { id: 'all', name: '全部' },
  { id: 'image', name: '图像处理' },
  { id: 'text', name: '文本处理' },
  { id: 'model', name: '模型加载' },
  { id: 'layout', name: '布局组件' },
];

const currentCategory = ref('all');
const searchQuery = ref('');
const pageSize = 6;
const currentPage = ref(1);
const components = ref([]); // 存储所有组件
const displayedComponents = ref([]);
const loading = ref(false);
const hasMore = ref(true);

// 获取所有组件
const getComponents = async () => {
  loading.value = true; // 开始加载
  try {
    const response = await fetchAllComponents(currentPage.value, pageSize);

    // 根据提供的 API 结构提取数据
    let newComponents = response.data?.data || [];

    // 如果没有获取到组件，给出提示并返回
    if (newComponents.length === 0) {
      ElMessage.warning('未找到任何组件');
      return;
    }

    // 确保每个组件都有必要的属性
    const processedComponents = newComponents.map(component => ({
      id: component.id,
      name: component.name,
      description: component.description,
      icon: component.icon,
      tags: component.tags,
      category: component.category
    }));

    // 第一页时重置，否则追加
    if (currentPage.value === 1) {
      components.value = processedComponents;
      displayedComponents.value = processedComponents;
    } else {
      components.value = [...components.value, ...processedComponents];
      displayedComponents.value = [...displayedComponents.value, ...processedComponents];
    }

    // 判断是否还有更多数据
    hasMore.value = processedComponents.length === pageSize;
  } catch (error) {
    components.value = []; // 在请求失败时确保 components 是一个空数组
    displayedComponents.value = [];
    hasMore.value = false;
  } finally {
    loading.value = false; // 结束加载
  }
};

// 筛选组件
const filteredComponents = computed(() => {
  let filtered = components.value || []; // 确保 filtered 是一个数组

  if (currentCategory.value !== 'all') {
    filtered = filtered.filter(
      (item) => item.category === currentCategory.value
    );
  }

  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase();
    filtered = filtered.filter(
      (item) =>
        item.name.toLowerCase().includes(query) ||
        item.description.toLowerCase().includes(query)
    );
  }

  return filtered;
});

// 加载更多组件
const loadMoreComponents = () => {
  if (loading.value || !hasMore.value) return;

  loading.value = true;

  // 直接获取新的组件页面
  getComponents();
};

// 检查滚动位置
const checkScroll = () => {
  const scrollHeight = document.documentElement.scrollHeight;
  const scrollTop = document.documentElement.scrollTop;
  const clientHeight = document.documentElement.clientHeight;

  if (scrollHeight - scrollTop - clientHeight < 100) {
    loadMoreComponents();
  }
};

// 重置组件显示
const resetComponents = () => {
  currentPage.value = 1;
  displayedComponents.value = [];
  hasMore.value = true;
  loadMoreComponents();
};

// 处理搜索
const handleSearch = () => {
  resetComponents();
};

// 导航到详情页
const router = useRouter();
const navigateToDetail = (id) => {
  router.push({
    name: 'componentDetail',
    params: { id: id.toString() }
  });
};

// 监听搜索和分类变化
watch([searchQuery, currentCategory], () => {
  resetComponents();
});

// 生命周期钩子
onMounted(() => {
  getComponents(); // 直接调用获取组件
  window.addEventListener('scroll', checkScroll);
});

onUnmounted(() => {
  window.removeEventListener('scroll', checkScroll);
});
</script>

<style scoped>
.components-page {
  min-height: 100vh;
  background: #111827;
}

.page-header {
  background: #1f2937;
  padding: 80px 0 40px;
  border-bottom: 1px solid #374151;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}

.header-content {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.title-section h1 {
  font-size: 3rem;
  margin-bottom: 16px;
  background: linear-gradient(135deg, #3450ff 0%, #00d0ff 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.description {
  font-size: 1.2rem;
  color: #9ca3af;
}

.search-box input {
  width: 100%;
  padding: 16px 24px;
  border: 2px solid #374151;
  border-radius: 12px;
  font-size: 1.1rem;
  background: #111827;
  color: #f3f4f6;
  transition: all 0.3s ease;
}

.search-box input:focus {
  outline: none;
  border-color: #3450ff;
}

.main-content {
  padding: 40px 0;
}

.categories {
  display: flex;
  gap: 16px;
  margin: 32px 0;
  overflow-x: auto;
  padding-bottom: 12px;
}

.category-btn {
  padding: 12px 24px;
  border: none;
  border-radius: 24px;
  background: #1f2937;
  color: #9ca3af;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
  font-size: 1rem;
}

.category-btn.active {
  background: #3450ff;
  color: #ffffff;
}

.components-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 32px;
  margin-top: 40px;
}

.component-card {
  background: #1f2937;
  border-radius: 16px;
  padding: 32px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid #374151;
}

.component-card:hover {
  transform: translateY(-4px);
  border-color: #3450ff;
}

.component-icon {
  width: 48px;
  height: 48px;
  margin-bottom: 24px;
}

.component-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.component-info h3 {
  font-size: 1.4rem;
  margin-bottom: 12px;
  color: #f3f4f6;
}

.component-info p {
  color: #9ca3af;
  font-size: 1rem;
  margin-bottom: 24px;
  line-height: 1.6;
}

.component-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.tag {
  padding: 6px 16px;
  background: #111827;
  border-radius: 20px;
  font-size: 0.9rem;
  color: #9ca3af;
}

@media (max-width: 768px) {
  .page-header {
    padding: 60px 0 32px;
  }

  .title-section h1 {
    font-size: 2.2rem;
  }

  .description {
    font-size: 1rem;
  }

  .components-grid {
    grid-template-columns: 1fr;
  }
}
</style>
